package 程序员面试金典;

/**
 * 面试题 04.12. 求和路径
 * 给定一棵二叉树，其中每个节点都含有一个整数数值(该值或正或负)。设计一个算法，打印节点数值总和等于某个给定值的所有路径的数量。注意，路径不一定非得从二叉树的根节点或叶节点开始或结束，但是其方向必须向下(只能从父节点指向子节点方向)。
 *
 * 示例:
 * 给定如下二叉树，以及目标和 sum = 22，
 *
 *               5
 *              / \
 *             4   8
 *            /   / \
 *           11  13  4
 *          /  \    / \
 *         7    2  5   1
 * 返回:
 *
 * 3
 * 解释：和为 22 的路径有：[5,4,11,2], [5,8,4,5], [4,11,7]
 * 提示：
 *
 * 节点总数 <= 10000
 */
public class T04_12 {
    //双重 dfs 外层深度遍历 遍历每一个节点  内层dfs 从此节点开始找到所有和为sun的路径 每找到一条 ans++; 直到叶子节点为止
    private int ans = 0;

    public int pathSum(TreeNode root, int sum) {

        if (root == null) {
            return ans;
        }
        dfs(root, sum, 0);
        pathSum(root.left, sum);
        pathSum(root.right, sum);
        return ans;

    }

    public void dfs(TreeNode root, int sum, int count) {
        if (root == null) return;

        if ((root.val + count) == sum) {
            ans++;
        }

        if (root.left != null) {
            dfs(root.left, sum, root.val + count);
        }
        if (root.right != null) {
            dfs(root.right, sum, root.val + count);
        }


    }

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
}
